//
// Created by 陈成 on 2019/9/19.
//

#include "InstU.h"

InstU::InstU(uint32_t pc, sc_bv<32> value, RegBank<REG_NUM> *r, RegBank<CSR_NUM> *csr, Mem *m) :
        Inst(pc, value, r, csr, m),
        imm   (value.range(31, 12)),
        rd    (value.range(11,  7)),
        opcode(value.range( 6,  0)){

}

uint32_t
InstU::exec() {
    uint32_t u32_rd = rd.to_uint();
    uint32_t u32_imm = (imm, sc_bv<12>(0)).to_uint();

    switch (opcode.to_uint()) {
    case 0b0001011: // LUI
        r->write(u32_rd, u32_imm);

        LOG("LUI RD: %d, IMM: %d", rd.to_uint(), imm.to_uint());
        LOG(" - %d", u32_imm);
        break;
    case 0b0001111: // AUIPC
        r->write(u32_rd, pc + u32_imm);

        LOG("AUIPC RD: %d, IMM: %d", rd.to_uint(), imm.to_uint());
        LOG(" - %d + %d", u32_imm, pc);
        break;
    default:
        assert(false);
        break;
    }

    return pc + 4;
}
